import express from 'express';
import cors from 'cors';
import helmet from 'helmet';
import dotenv from 'dotenv';
import rateLimit from 'express-rate-limit';
import winston from 'winston';
import path from 'path';
import { fileURLToPath } from 'url';

// 配置环境变量
dotenv.config({ override: true });

// 导入配置和工具
import db from './config/database.js';
import { initDatabase } from './config/initDatabase.js';
import routes from './routes/index.js';
import { securityStartupCheck } from './config/security.js';
import { securityMonitor, loginSecurityMonitor } from './middleware/securityMonitor.js';
import errorHandler, { asyncHandler } from './middleware/errorHandler.js';
import { metricsMiddleware } from './middleware/metricsMiddleware.js';
import { initializeBusinessMetrics } from './utils/metrics.js';
import structuredLogger from './utils/structuredLogger.js';
import auditService from './services/auditService.js';
import auditMiddleware from './middleware/auditMiddleware.js';
import queueManager from './config/queueConfig.js';
import queueService from './services/queueService.js';
import aiInferenceWorker from './workers/aiInferenceWorker.js';
import fileProcessingWorker from './workers/fileProcessingWorker.js';
import cleanupWorker from './workers/cleanupWorker.js';
import processManager from './config/processManager.js';

// 获取当前文件路径
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// 配置日志记录器
const logger = winston.createLogger({
  level: 'info',
  format: winston.format.combine(
    winston.format.timestamp(),
    winston.format.errors({ stack: true }),
    winston.format.json()
  ),
  transports: [
    new winston.transports.Console({
      format: winston.format.combine(
        winston.format.colorize(),
        winston.format.simple()
      )
    }),
    new winston.transports.File({ filename: 'logs/error.log', level: 'error' }),
    new winston.transports.File({ filename: 'logs/combined.log' })
  ]
});

// 创建Express应用
const app = express();

// P0-E安全修复：安全监控中间件（必须在helmet之前）
app.use(securityMonitor);

// 🚀 P0网络修复第一步：CORS优先配置（必须在helmet之前）
const allowedOrigins = [
  'http://localhost:8101',
  'http://127.0.0.1:8101'
];

app.use(cors({
  // 🚨 "外科手术"修复：强制允许localhost:8101，解决403 Forbidden问题
  origin: ['http://localhost:8101', 'http://127.0.0.1:8101'],
  credentials: true,
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'PATCH', 'HEAD'],
  allowedHeaders: [
    'Content-Type',
    'Authorization',
    'Accept',
    'Origin',
    'User-Agent',
    'X-Requested-With',
    'Cache-Control',
    'Pragma',
    'Expires',
    'X-CSRF-Token',
    'X-HTTP-Method-Override'
  ],
  maxAge: 86400 // 24小时，减少预检请求频率
}));

// 基础中间件 - 在CORS之后
app.use(helmet({
  crossOriginResourcePolicy: { policy: "cross-origin" }
}));

// 🚀 P0网络修复第二步：统一请求体大小限制为15MB（医疗图像支持）
app.use(express.json({ limit: '15mb' }));
app.use(express.urlencoded({ extended: true, limit: '15mb' }));

// 初始化审计中间件（在其他中间件之前）
app.use(auditMiddleware);

// 🚀 P0网络修复第三步：移除冲突的CORS配置，统一使用cors中间件
// 注释：原有的手动CORS头设置与cors中间件冲突，导致OPTIONS预检请求失败
// 现在完全依赖cors中间件处理所有CORS逻辑

// 静态文件服务（用于上传的图像）- 依赖全局CORS配置
// 🚀 P0网络修复：移除局部CORS配置，避免与全局cors中间件冲突
app.use('/uploads', express.static(path.join(__dirname, '../uploads')));

// API限流中间件（仅在非开发环境启用）
if (process.env.NODE_ENV !== 'development') {
  const limiter = rateLimit({
    windowMs: parseInt(process.env.RATE_LIMIT_WINDOW_MS) || 60000, // 1分钟
    max: parseInt(process.env.RATE_LIMIT_MAX_REQUESTS) || 10,       // 最多10次
    message: {
      success: false,
      message: '请求过于频繁，请稍后再试',
      data: null
    },
    standardHeaders: true,
    legacyHeaders: false,
  });
  app.use('/api', limiter);
}

// 请求日志中间件
app.use((req, res, next) => {
  logger.info(`${req.method} ${req.path}`, {
    ip: req.ip,
    userAgent: req.get('User-Agent'),
    timestamp: new Date().toISOString()
  });
  next();
});

// 指标跟踪中间件
app.use(metricsMiddleware);

// 统一响应格式中间件
app.use((req, res, next) => {
  const originalSend = res.send;
  res.send = function(data) {
    if (res.statusCode === 200 && typeof data === 'object' && !data.success) {
      data = {
        success: true,
        message: '操作成功',
        data: data
      };
    }
    return originalSend.call(this, data);
  };
  next();
});

// API路由
app.use('/api', routes);

// 全局错误处理中间件 - 使用新的综合错误处理系统
app.use(errorHandler);

// 启动服务器
const startServer = async () => {
  try {
    // 清理可能存在的监听器，防止内存泄漏
    process.removeAllListeners('SIGTERM');
    process.removeAllListeners('SIGINT');

    // 初始化MySQL数据库（包含数据迁移）
    logger.info('正在初始化MySQL数据库...');
    await db.initialize();
    logger.info('✅ MySQL数据库初始化完成');

    // 初始化审计服务
    logger.info('正在初始化审计服务...');
    await auditService.initialize();
    logger.info('✅ 审计服务初始化完成');

    // P0-D安全修复：启动时安全配置检查
    logger.info('🔒 正在执行安全配置检查...');
    const securityReport = securityStartupCheck();
    logger.info('✅ 安全配置检查完成');

    // 初始化业务指标
    logger.info('正在初始化业务指标...');
    initializeBusinessMetrics();
    logger.info('✅ 业务指标初始化完成');

    // 初始化队列系统
    logger.info('正在初始化队列系统...');
    await queueService.initialize();
    logger.info('✅ 队列服务初始化完成');

    // Phase 2: 初始化多进程管理器
    logger.info('🚀 正在初始化多进程管理器...');
    try {
      await processManager.initialize();
      logger.info('✅ 多进程管理器初始化完成');

      // 监听进程管理器事件
      processManager.on('metrics_collected', (metrics) => {
        logger.debug('进程指标收集', {
          totalWorkers: metrics.totalWorkers,
          totalTasksProcessed: metrics.totalTasksProcessed,
          correlationId: metrics.correlationId
        });
      });

      processManager.on('health_check_completed', (healthResults) => {
        if (healthResults.unhealthyWorkers > 0) {
          logger.warn('进程健康检查发现问题', {
            unhealthyWorkers: healthResults.unhealthyWorkers,
            totalWorkers: healthResults.totalWorkers
          });
        }
      });

      processManager.on('worker_status_change', (event) => {
        logger.debug('工作器状态变更', {
          workerId: event.workerId,
          type: event.type,
          status: event.status
        });
      });

    } catch (error) {
      logger.warn('多进程管理器初始化失败，使用降级模式', {
        error: error.message
      });
    }

    // 启动传统工作器（作为备用）
    logger.info('正在启动传统AI推理工作器...');
    await aiInferenceWorker.start();
    logger.info('✅ AI推理工作器启动完成');

    // 启动文件处理工作器
    logger.info('正在启动文件处理工作器...');
    await fileProcessingWorker.start();
    logger.info('✅ 文件处理工作器启动完成');

    // 启动清理工作器
    logger.info('正在启动清理工作器...');
    await cleanupWorker.start();
    logger.info('✅ 清理工作器启动完成');

    // 启动服务器
    const PORT = process.env.PORT || 4000;
    const server = app.listen(PORT, () => {
      logger.info(`🚀 EndoSight-UC 服务器启动成功!`);
      logger.info(`📍 服务地址: http://localhost:${PORT}`);
      logger.info(`🌍 环境: ${process.env.NODE_ENV || 'development'}`);
      logger.info(`📊 数据库: ${process.env.DB_NAME}`);
      logger.info(`📁 上传目录: ${process.env.UPLOAD_PATH}`);
    });

    // 优雅停机 - 处理nodemon重启信号
    const gracefulShutdown = (signal) => {
      logger.info(`收到${signal}信号，准备优雅关闭服务器...`);
      logger.info(`[PID: ${process.pid}] 停止接受新请求...`);

      // 1. 停止接受新请求
      server.close(async () => {
        try {
          logger.info('[Server] 所有HTTP连接已关闭');

          // 2. 关闭多进程管理器
          logger.info('[Server] 正在关闭多进程管理器...');
          try {
            await processManager.shutdown();
            logger.info('[Server] 多进程管理器已关闭');
          } catch (error) {
            logger.warn('[Server] 关闭多进程管理器时发生错误:', error.message);
          }

          // 3. 关闭数据库连接
          // 注意：如果使用连接池，在这里关闭
          logger.info('[Server] 正在关闭数据库连接...');
          // db.pool.end(() => { logger.info('数据库连接已关闭'); });

          // 4. 其他清理工作
          logger.info('[Server] 完成所有清理工作');
          logger.info(`[Server] ${signal}处理完成，干净退出`);
          process.exit(0);

        } catch (error) {
          logger.error('[Server] 关闭过程中发生错误:', error);
          process.exit(1);
        }
      });

      // 4. 强制超时机制：如果服务器在10秒内没有关闭，则强制退出
      const forceExit = setTimeout(() => {
        logger.error(`[Server] 无法在10秒内完成${signal}处理，强制退出`);
        process.exit(1);
      }, 10000);

      // 如果进程被提前杀死，清除超时器
      process.on('exit', () => {
        clearTimeout(forceExit);
      });
    };

    // 处理nodemon的重启信号(SIGUSR2)和其他终止信号
    const signals = ['SIGUSR2', 'SIGTERM', 'SIGINT'];
    signals.forEach((signal) => {
      process.once(signal, () => gracefulShutdown(signal));
    });

    return server;
  } catch (error) {
    logger.error('服务器启动失败:', error);
    process.exit(1);
  }
};

// 如果直接运行此文件，则启动服务器
console.log('启动检查:', {
  importMeta: import.meta.url,
  argv1: process.argv[1],
  currentFile: process.argv[1].replace(/\\/g, '/')
});

// 添加进程级别的错误处理
process.on('uncaughtException', (error) => {
  logger.error('未捕获的异常 (uncaughtException):', {
    error: error.message,
    stack: error.stack,
    pid: process.pid
  });

  // 不退出进程，但记录错误
  logger.error('进程继续运行，但发生了未捕获的异常');
});

process.on('unhandledRejection', (reason, promise) => {
  logger.error('未处理的Promise拒绝 (unhandledRejection):', {
    reason: reason,
    promise: promise,
    stack: reason instanceof Error ? reason.stack : String(reason)
  });

  // 不退出进程，但记录错误
  logger.error('进程继续运行，但发生了未处理的Promise拒绝');
});

// 直接启动服务器，移除复杂的路径检查
startServer();

export default app;// Trigger reload
